/**
 * 
 */
package com.hirstlogics.boxarrow.model;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;


import com.hirstlogics.boxarrow.box.Box;
import com.hirstlogics.boxarrow.box.BoxList;
import com.hirstlogics.boxarrow.xml.IO;
import com.hirstlogics.boxarrow.xml.Persist;

/**
 * @author steve
 *
 */
public class Model implements Persist {
	String name="";
	Description description=null;
	BoxList boxes = new BoxList();
	ArrowList arrows;
	DiagList diagrams;
	
	String fileName="";
	boolean persisted=false;
	boolean dirty=true;
	/**
	 * @return the description
	 */
	public Description getDescription() {
		return description;
	}
	/**
	 * @param description the description to set
	 */
	public void setDescription(Description description) {
		this.description = description;
	}
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
		dirty = true;
	}
	/**
	 * @return the dirty
	 */
	public boolean isDirty() {
		return dirty;
	}
	/**
	 * @return the fileName
	 */
	public String getFileName() {
		return fileName;
	}
	/**
	 * @return the persisted
	 */
	public boolean isPersisted() {
		return persisted;
	}
	
	public Model(String aName) {
		name = aName;
		Description blank = new Description("Model: "+aName);
		setDescription(blank);
	}
	
	/* (non-Javadoc)
	 * @see com.hirstlogics.boxarrow.model.Persist#render(javax.xml.stream.XMLStreamWriter)
	 */
	public void render(XMLStreamWriter writer) throws XMLStreamException {
		writer.writeStartElement(PREFIX, MODEL_TAG, BOXARROW);
		writer.writeAttribute("xmlns:ba",BOXARROW);
		writer.writeAttribute("name", getName());
		if (description!=null) description.render(writer);
		boxes.render(writer);
		writer.writeEndElement();
	}
	
	public boolean saveAs(String filePath) {
		File output = new File(filePath);
		boolean success;
		try {
			success = output.createNewFile() || output.canWrite();
			if (success) {
				fileName=filePath;
				FileWriter writer = new FileWriter(output);
				XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
				XMLStreamWriter outWriter = xmlof.createXMLStreamWriter(writer);
				outWriter.writeStartDocument();
				render(outWriter);
				outWriter.writeEndDocument();
				outWriter.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			success=false;
		} catch (XMLStreamException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			success=false;
		}
		persisted = success;
		dirty = !success;
		return success;
	}
	
	public boolean save() {
		return saveAs(fileName);
	}
	public static Model open(String filePath) {
		Model build = null;
		File input = new File(filePath);
		if (input.canRead()) {
			try {
				FileReader reader = new FileReader(input);
				XMLInputFactory xif = XMLInputFactory.newInstance();
                XMLStreamReader inReader = xif.createXMLStreamReader(reader);
                inReader.next();
                System.out.println("Local name: '"+inReader.getLocalName()+"'");
                build = IO.readModel(inReader);
                build.fileName = filePath;
                build.persisted = true;
                build.dirty = false;
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (XMLStreamException e) {
				e.printStackTrace();
			}
		}
		return build;
	}
	
	Description info() {
		return null;
	}
	
	public void addBox(Box newBox) {
		dirty=true;
		boxes.add(newBox);
	}
	
	public List<Box> findBoxesBy(String name) {
		List<Box> found = new ArrayList<Box>();
		for (int idx=0;idx<boxes.boxCount();idx++) {
			if (boxes.getName(idx).equals(name)) 
				found.add(boxes.getBox(idx));
		}
		return found;
	}
	
	
	public void addBoxTo(String name, Box newBox) {
		if (name.isEmpty()) addBox(newBox);
		else {
//			findBox(name).add(newBox);
		}
	}
	
	public void displayBoxes() {
		String names[] = null;
		names=getBoxNames();
		if (names==null) System.out.println("No Boxes");
		else { 
			System.out.print("Names: ["+names[0]);
			for (int idx=1;idx<names.length;idx++)
				System.out.print(", "+names[idx]);
			System.out.println("]");
			}
		}

	
	public void displayInfo() {
		System.out.println("Model name="+name);
		System.out.println("Description: "+getDescription());
		displayBoxes();
		if (isPersisted()) System.out.println("Model last saved as:"+getFileName());
		else System.out.println("Model never saved");
		if (isDirty()) System.out.println("Model needs saving");


	}
	
	public String[] getBoxNames() {
		
		int boxCount = boxes.boxCount();
		if (boxCount==0) return null;
		else {
			String[] names = new String[boxCount];
			for (int idx=0;idx<boxCount;idx++) {
				names[idx]=boxes.getName(idx);
			}
			return names;
		}
	}
	
}
